---
layout: default
nav: tutorial
---

<div class="container">

  <div class="row">
    <div class="col-md-12">

      <h1>Implementing A Click To Edit UI</h1>

      <p>This example offers an inline click-to-edit UI for a contact. When you click the button below the current
        UI will be replaced with an editing UI, without a full browser refresh. You can then update the user information
        or cancel the edit.</p>

      <p>Note that the "server side" implementation is mocked out using mockjax, so you can see the entire
        implementation.  Click the "Source Code" tab to see the code.</p>

      <h2>Explanation</h2>

      <ul>
        <li>
          The 'Click To Edit' button uses <a href="/attributes/ic-get-from.html"><code>ic-get-from</code></a> to
          issue a GET to <code>/contact/1/edit</code>, and targets the div surrounding the entire Contact UI using
          <a href="/attributes/ic-target.html"><code>ic-target</code></a>
        </li>
        <li>
          The server returns a form that replaces the content of the div.  The form uses the
          <a href="/attributes/ic-put-to"><code>ic-put-to</code></a> to issue a PUT to <code>/contact/1</code> and
          targets the same enclosing div.
        </li>
        <li>
          The 'Cancel' button uses <a href="/attributes/ic-get-from.html"><code>ic-get-from</code></a> to
          issue a GET to <code>/contact/1</code> and targets the same div.  The server-side handler at <code>/contact/1</code>
          should use the <code>ic-request</code> or <code>ic-target</code> parameter to differentiate between a full
          window request and this partial request.</a>
        </li>
      </ul>

      <h2>Demo</h2>

      <div>
        <ul class="demo-nav nav nav-pills">
          <li role="presentation" class="active"><a href="#demo" aria-controls="demo" role="tab" data-toggle="tab">Live Demo</a></li>
          <li role="presentation"><a href="#code" aria-controls="demo" role="tab" data-toggle="tab">Source Code</a></li>
        </ul>
      </div>

      <div class="tab-content">
        <div role="tabpanel" class="tab-pane active" id="demo">
  <!--
  This is the initial UI (which would normally be generated by the userDisplayTemplate below of course)
  Note that the button targets the outer div which encloses the entire contact UI because that's what we
  want to replace when the button is clicked.
  -->
  <div id="contact-div">
    <div><strong>First Name</strong>: Joe</div>
    <div><strong>Last Name</strong>: Smith</div>
    <div><strong>Email</strong>: joesmith@example.com</div>
    <button ic-target="#contact-div" ic-get-from="/contact/1/edit" class="btn btn-default">
      Click To Edit
    </button>
  </div>

  <script>

    //========================================================================
    // Mock Server-Side HTTP End Points
    //========================================================================
    $.mockjax({
      url: "/contact/1/edit",
      response: function (settings) {
        var mockUser = dataStore.findUser("1");
        this.responseText = userFormTemplate(mockUser);
      }
    });

    $.mockjax({
      url: "/contact/1",
      response: function (settings) {
        var mockUser = dataStore.findUser("1");
        var params = parseParams(settings.data);
        if (params['_method']== 'PUT') {
          mockUser.firstName = params['firstName'];
          mockUser.lastName = params['lastName'];
          mockUser.email = params['email'];
        }
        this.responseText = userDisplayTemplate(mockUser);
      }
    });

    //========================================================================
    // Mock Server-Side Templates
    //========================================================================
    function userFormTemplate(mockUser) {
      // Pretty simple bootstrap form, but note that the form uses an ic-put-to and the cancel button uses
      // an ic-get-from rather than the usual HTML attributes
      return '\
<form ic-put-to="/contact/1" ic-target="#contact-div"> \
  <div class="form-group"> \
    <label>First Name</label> \
    <input type="text" class="form-control" name="firstName" value="' + mockUser.firstName + '"> \
  </div> \
  <div class="form-group"> \
    <label>Last Name</label> \
    <input type="text" class="form-control" name="lastName" value="' + mockUser.lastName + '"> \
  </div> \
  <div class="form-group"> \
    <label>Email address</label> \
    <input type="email" class="form-control" name="email" value="' + mockUser.email + '"> \
  </div> \
  <button class="btn btn-default">Submit</button> \
  <button ic-get-from="/contact/1" ic-target="#contact-div" class="btn btn-danger">Cancel</button> \
</form>';
    }

    function userDisplayTemplate(mockUser) {
      return '\
<div><strong>First Name</strong>: ' + mockUser.firstName + '</div> \
<div><strong>Last Name</strong>: ' + mockUser.lastName + '</div> \
<div><strong>Email</strong>: ' + mockUser.email + '</div> \
<button ic-target="#contact-div" ic-get-from="/contact/1/edit" class="btn btn-default"> \
  Click To Edit \
</button>';
    }

    //========================================================================
    // Mock Data Store
    //========================================================================
    var dataStore = (function() {
      var mockUser = {
        "firstName": "Joe",
        "lastName": "Smith",
        "email": "joesmith@example.com"
      };
      return {
        findUser : function(id) {
          return mockUser
        }
      }
    })()

  </script>
        </div>
        <div role="tabpanel" class="tab-pane" id="code">
          <pre id="src-pre"></pre>
        </div>
      </div>

    </div>
    <script>
      $("#src-pre").text($("#demo").html());
    </script>

  </div>
</div>
